#include <iostream>
#include "AdvHeroFighter.h"
#include "HeroFighter.h"
#include "EnemyFighter.h"
using namespace std;

class Parent{
private:
        int a;
public:
        Parent(int a){
                this->a = a;
                //cout<<"a"<<endl;
        }

        virtual void print(){ //virtual 父类写了virtual,子类可写可不写
                cout <<"Parent 打印 a = "<<a<<endl;
        }
};

class Child : public Parent{
private:
        int b;
public:
        Child(int a, int b):Parent(a){
                this->b = b;
        }
        void print(){
                cout <<"Child 打印 b = "<<b<<endl;
        }
};

void howToPrint(Parent *base){
        base->print(); //一种调用不过语句 有多种表现年形态
}

void howToPrint(Parent &base){
        base.print();
}

//问题的引出(赋值兼容性原则遇上函数重写)
//在父类中重写的同名函数前加virtual关键字  才能实现多态 否则一直调用的是父类的函数
int main01(int argc, char const *argv[])
{
       Parent *base = NULL;
       Parent p1(20);
       Child c1(30, 30);
        
        base = &p1;
        base->print();//执行父类的打印函数

        base = &c1;
        base->print();//执行父类的打印函数 //面向对象新区求

        {
                Parent &base2 = p1;
                base2.print();//执行父类的打印函数

                Parent &base3 = c1; //base3是c1的别名
                base3.print();//执行父类的打印函数
        }

        //函数调用
        howToPrint(&p1); //执行父类的打印函数
        howToPrint(&c1);//执行父类的打印函数

        howToPrint(p1);//执行父类的打印函数
        howToPrint(c1);//执行父类的打印函数

        return 0;
}

//框架 多态威力
//1.framework给对象搭建舞台 看成一个框架
//15:20
void framework(HeroFighter *hf, EnemyFighter *ef)
{
        //不写virtual关键字 是静态连编 c++编译器根据HeroFilghter类型,去执行 这个类型的power函数 在编译器编译就确定了
        //动态联编 ：迟绑定 //在运行的时候,根据具体对象(具体的类型),执行不同对象的函数，表现成多态
        if(hf->power() > ef->attack()) //hf->power() 会用多态发生
        {
                cout<<"主角win"<<endl;
        }else{
                cout<<"主角刮掉"<<endl;
        }
}

//多态的使用
//多态的思想
//面向对象的3大概念
//封装: 突破了函数的概念...用类做函数参数的时候,可以是使用对象的属性 和对象的方法
//继承：A B 代码复用
//多台: 多态使用未来...

//多态很重要
//实现多态的三个条件
//c语言 简介赋值 是指针存在的最大意义
//是c语言的特有的现象(1 定义两个变量 2 建立关联 3 *p在被调用函数中去间接的修改实参的值)

//实现多态的三个条件
//1.要有继承
//2.要有虚函数重写 同名函数前还要加virtual
//3.用父类指针(父类引用)指向子类对象...
//多态是设计模式的基础,多态是框架的基础
int main(int argc, char const *argv[])
{
        HeroFighter hf;
        AdvHeroFighter advhf;
        EnemyFighter ef;

        framework(&hf, &ef);
        framework(&advhf, &ef);

        return 0;
}


//原来的使用
int main02(int argc, char const *argv[])
{
        HeroFighter hf;
        AdvHeroFighter advhf;
        EnemyFighter ef;

        if(hf.power()>ef.attack())
        {
                cout<<"主角win"<<endl;
        }else{
                cout<<"主角刮掉"<<endl;
        }

        if(advhf.power()>ef.attack())
        {
                cout<<"adv主角win"<<endl;
        }else{
                cout<<"adv主角刮掉"<<endl;
        }


        return 0;
}
